package com.qwc.blog.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qwc.blog.common.exception.BadRequestException;
import com.qwc.blog.entity.Resource;
import com.qwc.blog.entity.User;
import com.qwc.blog.entity.vo.resource.RouterVo;
import com.qwc.blog.mapper.ResourceMapper;
import com.qwc.blog.service.IResourceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.qwc.blog.common.constant.CommonConstant.*;
import static com.qwc.blog.common.constant.ResponseConstant.*;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author qwc
 * @since 2021-10-15
 */
@Service
@CacheConfig(cacheNames = CACHE)
@Slf4j
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements IResourceService {
    @Override
//    @Cacheable
    public List<RouterVo> getTreeRouter() {
        List<Resource> resourceList = baseMapper.selectList(Wrappers.<Resource>lambdaQuery()
                .eq(Resource::getStatus, YES)
                .orderByAsc(Arrays.asList(Resource::getPid, Resource::getOrderNum)));
        return RouterVo.getTreeRouter(resourceList);
    }

    @Override
    public List<Resource> selectResourceList(String resName, String status) {
        return baseMapper.selectList(Wrappers.<Resource>lambdaQuery()
                .like(StringUtils.isNotBlank(resName), Resource::getResName, resName)
                .eq(StringUtils.isNotBlank(status), Resource::getStatus, status)
                .orderByAsc(Arrays.asList(Resource::getPid, Resource::getOrderNum)));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addResource(Resource resource, String username) {
        checkResParams(resource);
        resource.setCreateBy(username);
        resource.setUpdateBy(username);
        baseMapper.insert(resource);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateResource(Resource resource, String username) {
        checkResParams(resource);
        if (resource.getResId().equals(resource.getPid())) {
            throw new BadRequestException(PID_WRONG);
        }
        resource.setUpdateBy(username);
        baseMapper.updateById(resource);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long resId) {
        List<Long> list = new ArrayList<>();
        list.add(resId);
        addSonId(resId, list);
        int i = baseMapper.deleteBatchIds(list);
        log.info("删除了{}条资源", i);
    }

    private void addSonId(Long resId, List<Long> list) {
        List<Resource> resources = baseMapper.selectList(Wrappers.<Resource>lambdaQuery().eq(Resource::getPid, resId));
        if (!resources.isEmpty()) {
            List<Long> collect = resources.stream().map(Resource::getResId).collect(Collectors.toList());
            list.addAll(collect);
            for (Long aLong : collect) {
                addSonId(aLong, list);
            }
        }
    }

    private void checkResParams(Resource resource) {
        List<Resource> resources = baseMapper.selectList(Wrappers.<Resource>lambdaQuery().eq(Resource::getResName, resource.getResName()));
        if (CollUtil.isNotEmpty(resources) && resources.stream().noneMatch(res -> res.getResId().equals(resource.getResId()))) {
            throw new BadRequestException(USED_NAME);
        }
        if (YES_INT.equals(resource.getIsFrame()) && !StringUtils.startsWithAny(resource.getPath(), HTTP, HTTPS)) {
            throw new BadRequestException(HTTP_WRONG);
        }
    }
}
